package com.zenithmind.document.pojo.query;

import com.zenithmind.common.pojo.query.BaseQueryDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档标签查询DTO
 * 遵循单一职责原则：专注于标签查询条件
 * 遵循开闭原则：支持查询条件的扩展
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "文档标签查询DTO")
public class DocumentTagQueryDTO extends BaseQueryDTO {

    @Schema(description = "标签名称", example = "Java")
    private String name;

    @Schema(description = "标签名称关键词", example = "java")
    private String nameKeyword;

    @Schema(description = "标签名称列表")
    private List<String> names;

    @Schema(description = "标签描述关键词", example = "编程")
    private String descriptionKeyword;

    @Schema(description = "标签颜色", example = "#FF5722")
    private String color;

    @Schema(description = "标签颜色列表")
    private List<String> colors;

    @Schema(description = "标签图标", example = "fa-java")
    private String icon;

    @Schema(description = "标签图标列表")
    private List<String> icons;

    @Schema(description = "标签分类", example = "编程语言")
    private String category;

    @Schema(description = "标签分类关键词", example = "编程")
    private String categoryKeyword;

    @Schema(description = "标签分类列表")
    private List<String> categories;

    @Schema(description = "父标签ID", example = "tag123456")
    private String parentTagId;

    @Schema(description = "父标签ID列表")
    private List<String> parentTagIds;

    @Schema(description = "标签级别", example = "1")
    private Integer level;

    @Schema(description = "最小标签级别", example = "1")
    private Integer minLevel;

    @Schema(description = "最大标签级别", example = "3")
    private Integer maxLevel;

    @Schema(description = "标签级别列表")
    private List<Integer> levels;

    @Schema(description = "最小排序权重", example = "100")
    private Integer minSortWeight;

    @Schema(description = "最大排序权重", example = "500")
    private Integer maxSortWeight;

    @Schema(description = "是否系统标签", example = "false")
    private Boolean isSystemTag;

    @Schema(description = "是否公开标签", example = "true")
    private Boolean isPublic;

    @Schema(description = "是否推荐标签", example = "true")
    private Boolean isRecommended;

    @Schema(description = "是否热门标签", example = "true")
    private Boolean isHot;

    @Schema(description = "别名关键词", example = "java")
    private String aliasKeyword;

    @Schema(description = "关键词", example = "编程")
    private String keyword;

    @Schema(description = "关键词列表")
    private List<String> keywords;

    @Schema(description = "最小标签权重", example = "0.5")
    private Double minWeight;

    @Schema(description = "最大标签权重", example = "2.0")
    private Double maxWeight;

    @Schema(description = "使用限制关键词", example = "maxUsage")
    private String usageRestrictionsKeyword;

    @Schema(description = "标签规则关键词", example = "autoApply")
    private String tagRulesKeyword;

    @Schema(description = "创建人ID", example = "user123456")
    private String creatorId;

    @Schema(description = "创建人ID列表")
    private List<String> creatorIds;

    @Schema(description = "创建来源", example = "MANUAL", allowableValues = {"MANUAL", "AUTO", "IMPORT", "SYSTEM"})
    private String createSource;

    @Schema(description = "创建来源列表")
    private List<String> createSources;

    @Schema(description = "语言代码", example = "zh-CN")
    private String languageCode;

    @Schema(description = "语言代码列表")
    private List<String> languageCodes;

    @Schema(description = "地域代码", example = "CN")
    private String regionCode;

    @Schema(description = "地域代码列表")
    private List<String> regionCodes;

    @Schema(description = "标签状态", example = "ACTIVE", allowableValues = {"ACTIVE", "INACTIVE", "PENDING", "DEPRECATED"})
    private String status;

    @Schema(description = "标签状态列表")
    private List<String> statuses;

    @Schema(description = "扩展属性关键词", example = "difficulty")
    private String extendedPropertiesKeyword;

    @Schema(description = "备注关键词", example = "系统")
    private String remarksKeyword;

    @Schema(description = "是否启用", example = "true")
    private Boolean isEnabled;

    @Schema(description = "审核状态", example = "APPROVED", allowableValues = {"PENDING", "APPROVED", "REJECTED"})
    private String reviewStatus;

    @Schema(description = "审核状态列表")
    private List<String> reviewStatuses;

    @Schema(description = "最小使用次数", example = "10")
    private Integer minUsageCount;

    @Schema(description = "最大使用次数", example = "1000")
    private Integer maxUsageCount;

    @Schema(description = "最小文档数量", example = "5")
    private Integer minDocumentCount;

    @Schema(description = "最大文档数量", example = "500")
    private Integer maxDocumentCount;

    @Schema(description = "是否有子标签", example = "true")
    private Boolean hasChildren;

    @Schema(description = "是否为根标签", example = "false")
    private Boolean isRoot;

    @Schema(description = "是否为叶子标签", example = "true")
    private Boolean isLeaf;

    @Schema(description = "是否有别名", example = "true")
    private Boolean hasAliases;

    @Schema(description = "是否有关键词", example = "true")
    private Boolean hasKeywords;

    @Schema(description = "是否有使用限制", example = "false")
    private Boolean hasUsageRestrictions;

    @Schema(description = "是否有标签规则", example = "true")
    private Boolean hasTagRules;

    @Schema(description = "创建时间开始", example = "2025-01-01T00:00:00")
    private LocalDateTime createTimeStart;

    @Schema(description = "创建时间结束", example = "2025-01-31T23:59:59")
    private LocalDateTime createTimeEnd;

    @Schema(description = "更新时间开始", example = "2025-01-01T00:00:00")
    private LocalDateTime updateTimeStart;

    @Schema(description = "更新时间结束", example = "2025-01-31T23:59:59")
    private LocalDateTime updateTimeEnd;

    @Schema(description = "最后使用时间开始", example = "2025-01-01T00:00:00")
    private LocalDateTime lastUsedTimeStart;

    @Schema(description = "最后使用时间结束", example = "2025-01-31T23:59:59")
    private LocalDateTime lastUsedTimeEnd;

    @Schema(description = "排序字段", example = "usageCount", allowableValues = {
            "createTime", "updateTime", "usageCount", "documentCount", "sortWeight", "weight", "name"
    })
    private String sortField;

    @Schema(description = "排序方向", example = "DESC", allowableValues = {"ASC", "DESC"})
    private String sortDirection;

    @Schema(description = "分组字段", example = "category", allowableValues = {
            "category", "level", "createSource", "status", "languageCode", "regionCode"
    })
    private String groupBy;

    @Schema(description = "统计类型", example = "COUNT", allowableValues = {"COUNT", "SUM", "AVG", "MAX", "MIN"})
    private String statisticsType;

    @Schema(description = "时间聚合粒度", example = "DAY", allowableValues = {"HOUR", "DAY", "WEEK", "MONTH"})
    private String timeGranularity;

    @Schema(description = "是否包含已删除", example = "false")
    private Boolean includeDeleted;

    @Schema(description = "是否只查询热门标签", example = "false")
    private Boolean onlyHotTags;

    @Schema(description = "是否只查询推荐标签", example = "false")
    private Boolean onlyRecommendedTags;

    @Schema(description = "是否只查询系统标签", example = "false")
    private Boolean onlySystemTags;

    @Schema(description = "是否只查询用户标签", example = "false")
    private Boolean onlyUserTags;

    @Schema(description = "是否只查询根标签", example = "false")
    private Boolean onlyRootTags;

    @Schema(description = "是否只查询叶子标签", example = "false")
    private Boolean onlyLeafTags;

    @Schema(description = "是否只查询活跃标签", example = "true")
    private Boolean onlyActiveTags;

    /**
     * 验证查询条件
     */
    public boolean isValid() {
        // 级别范围验证
        if (minLevel != null && maxLevel != null) {
            if (minLevel > maxLevel || minLevel < 1 || maxLevel > 10) return false;
        }
        
        // 权重范围验证
        if (minSortWeight != null && maxSortWeight != null) {
            if (minSortWeight > maxSortWeight || minSortWeight < 0) return false;
        }
        
        // 标签权重范围验证
        if (minWeight != null && maxWeight != null) {
            if (minWeight > maxWeight || minWeight < 0.1 || maxWeight > 10.0) return false;
        }
        
        // 使用次数范围验证
        if (minUsageCount != null && maxUsageCount != null) {
            if (minUsageCount > maxUsageCount || minUsageCount < 0) return false;
        }
        
        // 文档数量范围验证
        if (minDocumentCount != null && maxDocumentCount != null) {
            if (minDocumentCount > maxDocumentCount || minDocumentCount < 0) return false;
        }
        
        // 时间范围验证
        if (createTimeStart != null && createTimeEnd != null) {
            if (createTimeStart.isAfter(createTimeEnd)) return false;
        }
        
        if (updateTimeStart != null && updateTimeEnd != null) {
            if (updateTimeStart.isAfter(updateTimeEnd)) return false;
        }
        
        if (lastUsedTimeStart != null && lastUsedTimeEnd != null) {
            if (lastUsedTimeStart.isAfter(lastUsedTimeEnd)) return false;
        }
        
        return true;
    }

    /**
     * 是否有名称查询
     */
    public boolean hasNameQuery() {
        return name != null || nameKeyword != null || (names != null && !names.isEmpty());
    }

    /**
     * 是否有分类查询
     */
    public boolean hasCategoryQuery() {
        return category != null || categoryKeyword != null || (categories != null && !categories.isEmpty());
    }

    /**
     * 是否有层级查询
     */
    public boolean hasHierarchyQuery() {
        return parentTagId != null || (parentTagIds != null && !parentTagIds.isEmpty()) ||
               level != null || minLevel != null || maxLevel != null ||
               (levels != null && !levels.isEmpty()) || hasChildren != null ||
               isRoot != null || isLeaf != null;
    }

    /**
     * 是否有权重查询
     */
    public boolean hasWeightQuery() {
        return minSortWeight != null || maxSortWeight != null ||
               minWeight != null || maxWeight != null;
    }

    /**
     * 是否有属性查询
     */
    public boolean hasPropertyQuery() {
        return isSystemTag != null || isPublic != null ||
               isRecommended != null || isHot != null ||
               isEnabled != null;
    }

    /**
     * 是否有内容查询
     */
    public boolean hasContentQuery() {
        return aliasKeyword != null || keyword != null || (keywords != null && !keywords.isEmpty()) ||
               usageRestrictionsKeyword != null || tagRulesKeyword != null ||
               hasAliases != null || hasKeywords != null ||
               hasUsageRestrictions != null || hasTagRules != null;
    }

    /**
     * 是否有统计查询
     */
    public boolean hasStatisticsQuery() {
        return minUsageCount != null || maxUsageCount != null ||
               minDocumentCount != null || maxDocumentCount != null;
    }

    /**
     * 是否有时间范围查询
     */
    public boolean hasTimeRangeQuery() {
        return createTimeStart != null || createTimeEnd != null ||
               updateTimeStart != null || updateTimeEnd != null ||
               lastUsedTimeStart != null || lastUsedTimeEnd != null;
    }

    /**
     * 是否有关键词查询
     */
    public boolean hasKeywordQuery() {
        return nameKeyword != null || descriptionKeyword != null ||
               categoryKeyword != null || aliasKeyword != null ||
               keyword != null || usageRestrictionsKeyword != null ||
               tagRulesKeyword != null || extendedPropertiesKeyword != null ||
               remarksKeyword != null;
    }

    /**
     * 是否有地域查询
     */
    public boolean hasLocaleQuery() {
        return languageCode != null || (languageCodes != null && !languageCodes.isEmpty()) ||
               regionCode != null || (regionCodes != null && !regionCodes.isEmpty());
    }

    /**
     * 获取默认排序
     */
    public String getDefaultSort() {
        return "sortWeight DESC, usageCount DESC, createTime DESC";
    }

    /**
     * 是否查询热门标签
     */
    public boolean isQueryHotTags() {
        return onlyHotTags != null && onlyHotTags;
    }

    /**
     * 是否查询推荐标签
     */
    public boolean isQueryRecommendedTags() {
        return onlyRecommendedTags != null && onlyRecommendedTags;
    }

    /**
     * 是否查询系统标签
     */
    public boolean isQuerySystemTags() {
        return onlySystemTags != null && onlySystemTags;
    }

    /**
     * 是否查询用户标签
     */
    public boolean isQueryUserTags() {
        return onlyUserTags != null && onlyUserTags;
    }

    /**
     * 是否查询根标签
     */
    public boolean isQueryRootTags() {
        return onlyRootTags != null && onlyRootTags;
    }

    /**
     * 是否查询叶子标签
     */
    public boolean isQueryLeafTags() {
        return onlyLeafTags != null && onlyLeafTags;
    }

    /**
     * 是否查询活跃标签
     */
    public boolean isQueryActiveTags() {
        return onlyActiveTags != null && onlyActiveTags;
    }

    /**
     * 是否为复杂查询
     */
    public boolean isComplexQuery() {
        return hasNameQuery() || hasCategoryQuery() || hasHierarchyQuery() ||
               hasWeightQuery() || hasPropertyQuery() || hasContentQuery() ||
               hasStatisticsQuery() || hasTimeRangeQuery() || hasKeywordQuery() ||
               hasLocaleQuery();
    }

    /**
     * 获取有效级别范围
     */
    public int[] getEffectiveLevelRange() {
        int min = minLevel != null ? minLevel : 1;
        int max = maxLevel != null ? maxLevel : 10;
        return new int[]{min, max};
    }

    /**
     * 获取有效权重范围
     */
    public double[] getEffectiveWeightRange() {
        double min = minWeight != null ? minWeight : 0.1;
        double max = maxWeight != null ? maxWeight : 10.0;
        return new double[]{min, max};
    }
}
